package com.yupi.sqlfather.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yupi.sqlfather.common.BaseResponse;
import com.yupi.sqlfather.common.DeleteRequest;
import com.yupi.sqlfather.common.ErrorCode;
import com.yupi.sqlfather.common.ResultUtils;
import com.yupi.sqlfather.exception.BusinessException;
import com.yupi.sqlfather.model.dto.DataSourceAddRequest;
import com.yupi.sqlfather.model.dto.DataSourceQueryRequest;
import com.yupi.sqlfather.model.dto.DataSourceTestRequest;
import com.yupi.sqlfather.model.dto.DataSourceUpdateRequest;
import com.yupi.sqlfather.model.entity.DataSource;
import com.yupi.sqlfather.model.entity.User;
import com.yupi.sqlfather.service.DataSourceService;
import com.yupi.sqlfather.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * 数据源接口
 */
@RestController
@RequestMapping("/datasource")
@Slf4j
public class DataSourceController {

    @Resource
    private DataSourceService dataSourceService;

    @Resource
    private UserService userService;

    // region 增删改查

    /**
     * 创建数据源
     *
     * @param dataSourceAddRequest 数据源创建请求
     * @param request HTTP请求
     * @return 创建结果
     */
    @PostMapping("/add")
    public BaseResponse<Long> addDataSource(@RequestBody DataSourceAddRequest dataSourceAddRequest, HttpServletRequest request) {
        if (dataSourceAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        DataSource dataSource = new DataSource();
        BeanUtils.copyProperties(dataSourceAddRequest, dataSource);
        dataSourceService.validDataSource(dataSource, true);
        dataSource.setStatus(1);
        boolean result = dataSourceService.save(dataSource);
        if (!result) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        return ResultUtils.success(dataSource.getId());
    }

    /**
     * 删除数据源
     *
     * @param deleteRequest 删除请求
     * @param request HTTP请求
     * @return 删除结果
     */
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteDataSource(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        boolean result = dataSourceService.removeById(deleteRequest.getId());
        return ResultUtils.success(result);
    }

    /**
     * 更新数据源
     *
     * @param dataSourceUpdateRequest 数据源更新请求
     * @param request HTTP请求
     * @return 更新结果
     */
    @PostMapping("/update")
    public BaseResponse<Boolean> updateDataSource(@RequestBody DataSourceUpdateRequest dataSourceUpdateRequest, HttpServletRequest request) {
        if (dataSourceUpdateRequest == null || dataSourceUpdateRequest.getId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        DataSource dataSource = new DataSource();
        BeanUtils.copyProperties(dataSourceUpdateRequest, dataSource);
        dataSourceService.validDataSource(dataSource, false);
        boolean result = dataSourceService.updateById(dataSource);
        return ResultUtils.success(result);
    }

    /**
     * 根据 id 获取数据源
     *
     * @param id 数据源ID
     * @param request HTTP请求
     * @return 数据源信息
     */
    @GetMapping("/get")
    public BaseResponse<DataSource> getDataSourceById(long id, HttpServletRequest request) {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        DataSource dataSource = dataSourceService.getById(id);
        return ResultUtils.success(dataSource);
    }

    /**
     * 获取数据源列表
     *
     * @param dataSourceQueryRequest 数据源查询请求
     * @param request HTTP请求
     * @return 数据源列表
     */
    @GetMapping("/list/page")
    public BaseResponse<Page<DataSource>> listDataSourceByPage(DataSourceQueryRequest dataSourceQueryRequest,
            HttpServletRequest request) {
        if (dataSourceQueryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long current = dataSourceQueryRequest.getCurrent();
        long pageSize = dataSourceQueryRequest.getPageSize();
        // 限制爬虫
        if (pageSize > 50) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        QueryWrapper<DataSource> queryWrapper = new QueryWrapper<>();
        String name = dataSourceQueryRequest.getName();
        String type = dataSourceQueryRequest.getType();
        if (StringUtils.isNotBlank(name)) {
            queryWrapper.like("name", name);
        }
        if (StringUtils.isNotBlank(type)) {
            queryWrapper.eq("type", type);
        }
        Page<DataSource> dataSources = dataSourceService.page(new Page<>(current, pageSize), queryWrapper);
        return ResultUtils.success(dataSources);
    }

    // endregion

    /**
     * 测试数据源连接
     *
     * @param dataSourceTestRequest 数据源测试请求
     * @param request HTTP请求
     * @return 测试结果
     */
    @PostMapping("/test")
    public BaseResponse<Boolean> testDataSource(@RequestBody DataSourceTestRequest dataSourceTestRequest, HttpServletRequest request) {
        if (dataSourceTestRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        DataSource dataSource = new DataSource();
        BeanUtils.copyProperties(dataSourceTestRequest, dataSource);
        boolean result = dataSourceService.testConnection(dataSource);
        return ResultUtils.success(result);
    }

    /**
     * 执行SQL
     *
     * @param dataSourceId 数据源ID
     * @param sql SQL语句
     * @param request HTTP请求
     * @return 执行结果
     */
    @PostMapping("/execute")
    public BaseResponse<Object> executeSql(@RequestParam Long dataSourceId, @RequestParam String sql,
            HttpServletRequest request) {
        if (dataSourceId == null || StringUtils.isBlank(sql)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        Object result = dataSourceService.executeSql(dataSourceId, sql);
        return ResultUtils.success(result);
    }
}
